package com.glp.work.flow.service.impl;

import com.github.pagehelper.PageInfo;
import com.github.pagehelper.page.PageMethod;
import com.glp.fbs.api.dto.user.PersonInfoDto;
import com.glp.work.flow.constant.APICode;
import com.glp.work.flow.constant.FLMsgEventEnum;
import com.glp.work.flow.constant.OrderStatus;
import com.glp.work.flow.exception.APIException;
import com.glp.work.flow.mapper.*;
import com.glp.work.flow.pojo.*;
import com.glp.work.flow.request.*;
import com.glp.work.flow.response.ToDoTasksResponse;
import com.glp.work.flow.response.UserTaskDto;
import com.glp.work.flow.response.WfOrderResponse;
import com.glp.work.flow.response.WfOrderResultDTO;
import com.glp.work.flow.service.*;
import com.glp.work.flow.service.client.PermissionClient;
import com.glp.work.flow.utils.DateUtils;
import com.glp.work.flow.utils.VersionUtils;
import com.glp.work.flow.workflow.plugin.flowable.constant.FlowConstant;
import com.glp.work.flow.workflow.plugin.flowable.service.FlowTaskService;
import com.glp.work.flow.workflow.plugin.flowable.util.DateUtil;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.collections.CollectionUtils;
import org.apache.commons.lang3.StringUtils;
import org.flowable.engine.HistoryService;
import org.flowable.engine.RuntimeService;
import org.flowable.engine.TaskService;
import org.flowable.engine.history.HistoricActivityInstance;
import org.flowable.engine.impl.persistence.entity.ExecutionEntityImpl;
import org.flowable.engine.runtime.ActivityInstance;
import org.flowable.engine.runtime.Execution;
import org.flowable.task.api.Task;
import org.flowable.task.api.TaskQuery;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import tk.mybatis.mapper.entity.Example;

import javax.annotation.Resource;
import java.util.*;
import java.util.stream.Collectors;

/**
 * 工作流查询服务
 *
 * @author jhuang1
 */
@Service
@Slf4j
public class WfProcessQueryServiceImpl implements WfProcessQueryService {
    @Resource
    private WfOrderMapper wfOrderMapper;
    @Resource
    private FlowTaskService flowTaskServiceImpl;
    @Resource
    private WfFormService wfFormService;
    @Autowired
    TaskService taskService;
    @Autowired
    RuntimeService runtimeService;
    @Resource
    HistoryService historyService;

    @Autowired
    private WfPlatformDefMapper wfPlatformDefMapper;
    @Autowired
    private WfFormExampleMapper wfFormExampleMapper;
    @Resource
    private WfTaskAssignMapper wfTaskAssignMapper;
    @Resource
    private WfTaskAssignNodeMapper wfTaskAssignNodeMapper;
    @Resource
    private PermissionClient permissionClient;
    @Resource
    private WfPlatformDefService wfPlatformDefService;
    @Resource
    private UserService userService;

    @Override
    public PageInfo<WfOrderResultDTO> queryToDoTasks(WfOrderQueryDTO wfOrderQueryDTO) {


        if (wfOrderQueryDTO.getAppId() != null) {
            /**
             * 根据平台appId得到调用类型
             */
            Example example = new Example(WfPlatformDef.class);
            example.createCriteria()
                    .andEqualTo("platformId", wfOrderQueryDTO.getAppId());
            WfPlatformDef wfPlatformDef = wfPlatformDefMapper.selectOneByExample(example);
            Map<String, Object> params = buildQueryParams(wfOrderQueryDTO);
            PageInfo<WfOrderResultDTO> result = PageMethod.startPage(
                    wfOrderQueryDTO.getPageNum(), wfOrderQueryDTO.getPageSize()).doSelectPageInfo(() -> wfOrderMapper.queryToDoTasksOrder(params));
            result.getList().forEach(wfOrderResultDTO -> {
                wfOrderResultDTO.setVersion(VersionUtils.getVersion(wfOrderResultDTO.getVersion()));
                getDynamicForm(wfPlatformDef, wfOrderResultDTO);
            });
            return result;

        } else {
            Map<String, Object> params = buildQueryParams(wfOrderQueryDTO);
            PageInfo<WfOrderResultDTO> result = PageMethod.startPage(
                    wfOrderQueryDTO.getPageNum(), wfOrderQueryDTO.getPageSize()).doSelectPageInfo(() -> wfOrderMapper.queryToDoTasksOrder(params));
            result.getList().forEach(wfOrderResultDTO -> {
                Task task = taskService.createTaskQuery().taskId(wfOrderResultDTO.getTaskId()).singleResult();
                wfOrderResultDTO.setVersion(VersionUtils.getVersion(wfOrderResultDTO.getVersion()));
                wfOrderResultDTO.setCurrentNode(task.getName());
            });
            return result;
        }

    }


    private Map<String, Object> buildQueryParams(WfOrderQueryDTO wfOrderQueryDTO) {
        Map<String, Object> params = new HashMap<>(8);
        params.put("userNo", wfOrderQueryDTO.getUserNo());
        if (StringUtils.isNotEmpty(wfOrderQueryDTO.getAppId())) {
            params.put("appId", wfOrderQueryDTO.getAppId());
            PersonInfoDto personInfo = userService.getPersonInfo(wfOrderQueryDTO.getUserNo(), wfOrderQueryDTO.getAppId());
            if (personInfo != null) {
                List<String> businessRangeCodes = personInfo.getBusinessRangeCodes();
                if (CollectionUtils.isNotEmpty(businessRangeCodes)) {
                    Map<String, List<String>> businessRangeCodeList = new HashMap();
                    businessRangeCodeList.put(wfOrderQueryDTO.getAppId(), businessRangeCodes);
                    params.put("businessRangeCodeList", businessRangeCodeList);
                }
            }
        } else {
            Example example = new Example(WfPlatformDef.class);
            example.createCriteria()
                    .andEqualTo("type", 0);
            List<WfPlatformDef> list = wfPlatformDefMapper.selectByExample(example);
            List<String> appIds = list.stream().map(WfPlatformDef::getPlatformId).collect(Collectors.toList());
            params.put("appIds", appIds);

            Map<String, List<String>> businessRangeCodeList = new HashMap();
            appIds.forEach(appId -> {
                PersonInfoDto personInfo = userService.getPersonInfo(wfOrderQueryDTO.getUserNo(), appId);
                if (personInfo != null) {
                    List<String> businessRangeCodes = personInfo.getBusinessRangeCodes();
                    if (CollectionUtils.isNotEmpty(businessRangeCodes)) {
                        businessRangeCodeList.put(appId, businessRangeCodes);
                    }
                }
            });
            params.put("businessRangeCodeList", businessRangeCodeList);
        }
        // Map<businessRangeCodeList,Map<appId,businessRangeCodes>
        if (StringUtils.isNotBlank(wfOrderQueryDTO.getWfId())) {
            params.put("wfId", "%" + wfOrderQueryDTO.getWfId() + "%");
        }
        if (StringUtils.isNotBlank(wfOrderQueryDTO.getOrderId())) {
            params.put("orderId", "%" + wfOrderQueryDTO.getOrderId() + "%");
        }
        if (StringUtils.isNotBlank(wfOrderQueryDTO.getBatch())) {
            params.put("batch", "%" + wfOrderQueryDTO.getBatch() + "%");
        }
        if (StringUtils.isNotBlank(wfOrderQueryDTO.getOrderTitle())) {
            params.put("orderTitle", "%" + wfOrderQueryDTO.getOrderTitle() + "%");
        }
        if (StringUtils.isNotBlank(wfOrderQueryDTO.getOrderStatus())
                && !OrderStatus.PROCESSED.getCode().equals(wfOrderQueryDTO.getOrderStatus())
                && !OrderStatus.ALL.getCode().equals(wfOrderQueryDTO.getOrderStatus())) {
            params.put("orderStatus", wfOrderQueryDTO.getOrderStatus());
        }
        if (CollectionUtils.isNotEmpty(wfOrderQueryDTO.getIndex1s())) {
            params.put("index1s", wfOrderQueryDTO.getIndex1s());
        }
        if (CollectionUtils.isNotEmpty(wfOrderQueryDTO.getIndex2s())) {
            params.put("index2s", wfOrderQueryDTO.getIndex2s());
        }

        if (CollectionUtils.isNotEmpty(wfOrderQueryDTO.getIndex3s())) {
            params.put("index3s", wfOrderQueryDTO.getIndex3s());
        }
        if (CollectionUtils.isNotEmpty(wfOrderQueryDTO.getRoleCode())) {
            params.put("codes", wfOrderQueryDTO.getRoleCode());
        }
        if (null != wfOrderQueryDTO.getCreateTimeStart()) {
            params.put("createTimeStart", DateUtils.formatDate(wfOrderQueryDTO.getCreateTimeStart(), DateUtils.FORMAT));
        }
        if (null != wfOrderQueryDTO.getCreateTimeEnd()) {
            params.put("createTimeEnd", DateUtils.calculateDay(
                    DateUtils.formatDate(wfOrderQueryDTO.getCreateTimeEnd(), DateUtils.FORMAT), 1, true));
        }
        if (null != wfOrderQueryDTO.getEndTimeStart()) {
            params.put("endTimeStart", DateUtils.formatDate(wfOrderQueryDTO.getEndTimeStart(), DateUtils.FORMAT));
        }
        if (null != wfOrderQueryDTO.getEndTimeEnd()) {
            params.put("endTimeEnd", DateUtils.calculateDay(
                    DateUtils.formatDate(wfOrderQueryDTO.getEndTimeEnd(), DateUtils.FORMAT), 1, true));
        }
        if (StringUtils.isNotBlank(wfOrderQueryDTO.getProcessId())) {
            params.put("processId", wfOrderQueryDTO.getProcessId());
        }

        if (CollectionUtils.isNotEmpty(wfOrderQueryDTO.getProDefKeys())) {
            params.put("proDefKeys", wfOrderQueryDTO.getProDefKeys());
        }
        if (StringUtils.isNotBlank(wfOrderQueryDTO.getCreateUser())) {
            params.put("createUser", "%" + wfOrderQueryDTO.getCreateUser() + "%");
        }
        return params;
    }


    @Override
    public PageInfo<WfOrderResultDTO> queryDoneTasks(WfOrderQueryDTO wfOrderQueryDTO) {

        if (wfOrderQueryDTO.getAppId() != null) {
            /**
             * 根据平台appId得到调用类型
             */

            Example example = new Example(WfPlatformDef.class);
            example.createCriteria()
                    .andEqualTo("platformId", wfOrderQueryDTO.getAppId());
            WfPlatformDef wfPlatformDef = wfPlatformDefMapper.selectOneByExample(example);

            Map<String, Object> params = buildQueryParams(wfOrderQueryDTO);
            PageInfo<WfOrderResultDTO> result = PageMethod.startPage(
                    wfOrderQueryDTO.getPageNum(), wfOrderQueryDTO.getPageSize()).doSelectPageInfo(() -> wfOrderMapper.queryDoneTasksOrder(params));
            result.getList().forEach(wfOrderResultDTO -> {
                wfOrderResultDTO.setVersion(VersionUtils.getVersion(wfOrderResultDTO.getVersion()));
                getDynamicForm(wfPlatformDef, wfOrderResultDTO);
            });
            return result;
        } else {
            Map<String, Object> params = buildQueryParams(wfOrderQueryDTO);
            PageInfo<WfOrderResultDTO> result = PageMethod.startPage(
                    wfOrderQueryDTO.getPageNum(), wfOrderQueryDTO.getPageSize()).doSelectPageInfo(() -> wfOrderMapper.queryDoneTasksOrder(params));
            result.getList().forEach(wfOrderResultDTO -> wfOrderResultDTO.setVersion(VersionUtils.getVersion(wfOrderResultDTO.getVersion())));
            return result;
        }
    }


    /**
     * 根据调用类型得到流程处理数据
     * 外部调用，需要传入appId，工单系统内部不会传入appId
     */
    private void getDynamicForm(WfPlatformDef wfPlatformDef, WfOrderResultDTO action) {
        /*
         * 根据调用类型得到流程处理数据
         */
        if (wfPlatformDef != null) {
            if (wfPlatformDef.getType() == 1) {
                Example example1 = new Example(WfFormExample.class);
                example1.createCriteria().andEqualTo("processId", action.getProcessId());
                List<WfFormExample> wfFormExamples = wfFormExampleMapper.selectByExample(example1);
                wfFormExamples.stream().filter(wfFormExample -> wfFormExample.getParentId() == null).distinct().collect(Collectors.toList()).forEach(wfFormExample -> {
                    action.setDynamicForm(wfFormExample.getProcessData());
                });
            }
        }
    }

    @Override
    public WfOrderResponse queryOrderDetail(String userNo, WfOrderDetailQueryDTO dto) {
        if (StringUtils.isBlank(dto.getProcessId())
                && StringUtils.isBlank(dto.getTaskId())) {
            throw new APIException(APICode.INVALID_PARAMETER, "流程ID和任务ID不能都为空！");
        }

        WfOrderResponse wfOrderResponse = new WfOrderResponse();
        //获得工单详情数据
        WfOrder order = new WfOrder();

        /*
         * 根据taskid获取当前任务处理人或者
         * 根据processId获取taskId，（多实例会签情况下，需要根据processId和userNo来获取taskId），
         * 如果是分配到角色情况下，可以直接根据processId查询任务，此时只有一个任务实例
         */
        if (StringUtils.isNotBlank(dto.getTaskId())) {
            wfOrderResponse.setTaskId(dto.getTaskId());
            Task task = taskService.createTaskQuery().taskId(dto.getTaskId()).singleResult();
            if (task != null) {
                String processId = task.getProcessInstanceId();
                dto.setProcessId(processId);
                order.setProcessId(dto.getProcessId());
                order = wfOrderMapper.selectOne(order);
                if (null == order) {
                    log.warn("工单不存在！工单系统流程实例ID(processId)：{}", dto.getProcessId());
                    throw new APIException(APICode.NOT_FOUND, "工单不存在！");
                }
                log.info("根据taskId获取执行中任务的处理人");
                List<String> candidate = flowTaskServiceImpl.getCandidate(task);
                String substring = candidate.toString().substring(1, candidate.toString().length() - 1);
                wfOrderResponse.setProcessor(substring);
                wfOrderResponse.setCurrentNode(task.getName());
                WfTaskAssign wfTaskAssign = new WfTaskAssign();
                wfTaskAssign.setProcDefId(task.getProcessDefinitionId());
                wfTaskAssign.setTaskDefId(task.getTaskDefinitionKey());
                wfTaskAssign = wfTaskAssignMapper.selectOne(wfTaskAssign);
                wfOrderResponse.setSms(wfTaskAssign.getSms());
                if (wfTaskAssign.getOptionType() != null) {
                    wfOrderResponse.setOptionList(Arrays.asList(wfTaskAssign.getOptionType().split(",")));
                }
            }
        } else {
            order.setProcessId(dto.getProcessId());
            order = wfOrderMapper.selectOne(order);
            if (null == order) {
                log.warn("工单不存在！工单系统流程实例ID(processId)：{}", dto.getProcessId());
                throw new APIException(APICode.NOT_FOUND, "工单不存在！");
            }
            Task task = null;
            TaskQuery taskQuery = taskService.createTaskQuery().processInstanceId(dto.getProcessId());
            List<Task> list = taskQuery.taskCandidateOrAssigned(userNo).list();
            if (CollectionUtils.isNotEmpty(list)) {
                task = list.get(0);
                wfOrderResponse.setTaskId(task.getId());
            } else {
                List<String> roleList = userService.personRoles(userNo, order.getAppId());
                log.info("用户对应的角色信息请求参数:{}", roleList);
                if (CollectionUtils.isNotEmpty(roleList)) {
                    List<Task> taskList = taskService.createTaskQuery().processInstanceId(dto.getProcessId()).list();
                    if (CollectionUtils.isNotEmpty(taskList)) {
                        task = taskList.get(0);
                        task = taskService.createTaskQuery().taskId(task.getId()).taskCandidateGroupIn(roleList).singleResult();
                        if (task != null) {
                            wfOrderResponse.setTaskId(task.getId());
                        }
                    }
                }
            }

            log.info("根据processId得到任务后，获取执行中任务的处理人");
            if (task != null) {
                List<String> candidate = flowTaskServiceImpl.getCandidate(task);
                String substring = candidate.toString().substring(1, candidate.toString().length() - 1);
                wfOrderResponse.setProcessor(substring);
                wfOrderResponse.setCurrentNode(task.getName());
            }
        }

        BeanUtils.copyProperties(order, wfOrderResponse);
        WfPlatformDef wfPlatformDef = new WfPlatformDef();
        wfPlatformDef.setPlatformId(order.getAppId());
        wfPlatformDef = wfPlatformDefMapper.selectOne(wfPlatformDef);
        wfOrderResponse.setPlatformame(wfPlatformDef.getPlatformName());
        if (OrderStatus.PROCESSING.getCode().equals(order.getOrderStatus()) ||
                OrderStatus.REJECT.getCode().equals(order.getOrderStatus())) {
            wfOrderResponse.setTotalTime(DateUtil.getDistanceTime(DateUtils.getCurrent().getTime() - order.getCreateTime().getTime()));
        }


        log.info("获取流转历史列表");
        List<FlowTaskHistoryDTO> flowTaskHistoryDtoList = new ArrayList<>();
        if (StringUtils.isBlank(dto.getShowLevel())
                || "A".equals(dto.getShowLevel())) {
            flowTaskHistoryDtoList = flowTaskServiceImpl.queryTaskHistories(order.getProcessId());
        } else if ("B".equals(dto.getShowLevel())) {
            flowTaskHistoryDtoList = flowTaskServiceImpl.queryHistoriesOfLevel(order.getProcessId(), dto.getShowLevel());
        }

        wfOrderResponse.setCommentList(flowTaskHistoryDtoList);

        log.info("处理消耗时间开始");
        for (FlowTaskHistoryDTO flowTaskHistoryDTO : flowTaskHistoryDtoList) {
            if (StringUtils.isNoneBlank(flowTaskHistoryDTO.getTimeConsuming())) {
                flowTaskHistoryDTO.setTimeConsuming(DateUtil.getDistanceTime(Long.parseLong(flowTaskHistoryDTO.getTimeConsuming()) / 1000 * 1000));
            }
        }

        log.info("获取所有流转节点");
        List<UserTaskDto> flowtaskList = flowTaskServiceImpl.queryProcessUserTasks(order.getProcessId());
        wfOrderResponse.setUserTaskList(flowtaskList);

        WfFormExample formExample = null;
        if (StringUtils.isNotBlank(dto.getTaskId())) {
            formExample = wfFormService.queryFormExample(order.getProcessId());
        } else {
            formExample = wfFormService.queryHistoryFormExample(order.getProcessId());
        }

        if (formExample != null) {
            wfOrderResponse.setFormCode(formExample.getFormCode());
            wfOrderResponse.setFormContent(formExample.getFormContent());
            wfOrderResponse.setFormData(formExample.getProcessData());
            wfOrderResponse.setFormName(formExample.getFormName());
        }

        return wfOrderResponse;
    }

    @Override
    public List<FlowTaskHistoryDTO> queryHistory(String orderId, String appId) {
        WfOrder wfOrder = new WfOrder();
        wfOrder.setOrderId(orderId);
        wfOrder.setAppId(appId);
        List<WfOrder> orderList = wfOrderMapper.select(wfOrder);
        if (CollectionUtils.isEmpty(orderList)) {
            throw new APIException(APICode.NOT_FOUND, "工单不存在！");
        }
        //获取流转历史列表
        return flowTaskServiceImpl.queryTaskHistories(wfOrder.getProcessId());
    }

    @Override
    public List<ToDoTasksResponse> totalToDoTasks(ToDoTasksRequest req) {
        WfOrderQueryDTO wfOrderQueryDTO = new WfOrderQueryDTO();
        wfOrderQueryDTO.setUserNo(req.getUserNo());
        wfOrderQueryDTO.setAppId(req.getAppId());
        List<String> list = userService.personRoles(wfOrderQueryDTO.getUserNo(), req.getAppId());
        log.info("用户对应的角色信息,请求参数:{}", list);
        if (StringUtils.isNotEmpty(wfOrderQueryDTO.getAppId())) {
            List<String> userCodeList = userService.personRoles(wfOrderQueryDTO.getUserNo(), wfOrderQueryDTO.getAppId());
            wfOrderQueryDTO.setRoleCode(userCodeList);
        } else {
            List<String> roleCodes = userService.getPersonAllEnableRoles(req.getUserNo());
            wfOrderQueryDTO.setRoleCode(roleCodes);
        }
        wfOrderQueryDTO.setOrderStatus(OrderStatus.PROCESSING.getCode());
        Map<String, Object> params = buildQueryParams(wfOrderQueryDTO);
        List<WfOrderResultDTO> srcList = wfOrderMapper.queryToDoTasksOrderQuantity(params);
        List<ToDoTasksResponse> targetList = new ArrayList<>();
        if (CollectionUtils.isNotEmpty(srcList)) {
            Map<String, List<WfOrderResultDTO>> collect = srcList.stream().filter(item -> StringUtils.isNoneBlank(item.getAppId()))
                    .collect(Collectors.groupingBy(WfOrderResultDTO::getAppId));
            Set<Map.Entry<String, List<WfOrderResultDTO>>> entries = collect.entrySet();
            for (Map.Entry<String, List<WfOrderResultDTO>> entry : entries) {
                ToDoTasksResponse target = new ToDoTasksResponse();
                target.setAppId(entry.getKey());
                target.setTotal(entry.getValue().size());
                if (StringUtils.isBlank(req.getAppId())) {
                    targetList.add(target);
                } else {
                    if (entry.getKey().equals(req.getAppId())) {
                        targetList.add(target);
                    }
                }
            }
        }
        return targetList;
    }

    @Override
    public ToDoTasksResponse querytotalToDoTasksHeaders(String appId, String userNo) {
        WfOrderQueryDTO wfOrderQueryDTO = new WfOrderQueryDTO();
        wfOrderQueryDTO.setAppId(appId);
        wfOrderQueryDTO.setUserNo(userNo);
        List<String> list = userService.personRoles(wfOrderQueryDTO.getUserNo(), appId);
        log.info("用户对应的角色信息,请求参数:{}", list);
        if (StringUtils.isNotEmpty(wfOrderQueryDTO.getAppId())) {
            List<String> userCodeList = userService.personRoles(wfOrderQueryDTO.getUserNo(), wfOrderQueryDTO.getAppId());
            wfOrderQueryDTO.setRoleCode(userCodeList);
        } else {
            List<String> roleCodes = userService.getPersonAllEnableRoles(userNo);
            wfOrderQueryDTO.setRoleCode(roleCodes);
        }
        wfOrderQueryDTO.setOrderStatus(OrderStatus.PROCESSING.getCode());
        Map<String, Object> params = buildQueryParams(wfOrderQueryDTO);
        List<WfOrderResultDTO> srcList = wfOrderMapper.queryToDoTasksOrderQuantity(params);
        ToDoTasksResponse toDoTasksResponset = new ToDoTasksResponse();
        if (CollectionUtils.isNotEmpty(srcList)) {
            toDoTasksResponset.setAppId(appId);
            toDoTasksResponset.setMsgNums(srcList.size());
        } else {
            toDoTasksResponset.setAppId(appId);
            toDoTasksResponset.setMsgNums(0);
        }
        return toDoTasksResponset;
    }

    @Override
    public List<FlowTaskHistoryDTO> queryHistoryUserTask(String procInstanceId, String taskId) {
        log.info("获取历史中可驳回的节点，已经走过的节点");
        List<HistoricActivityInstance> hisTasks = historyService.createHistoricActivityInstanceQuery()
                .processInstanceId(procInstanceId)
                .finished()
                .list().stream().filter(a -> a.getActivityType().equals("userTask")).collect(Collectors.toList());
        if (org.flowable.editor.language.json.converter.util.CollectionUtils.isNotEmpty(hisTasks)) {
            List<Execution> executions = runtimeService.createExecutionQuery().processInstanceId(procInstanceId).list();
            if (org.flowable.editor.language.json.converter.util.CollectionUtils.isNotEmpty(executions)) {
                executions = executions.stream().filter(predicate -> {
                    if (predicate instanceof ExecutionEntityImpl) {
                        if (((ExecutionEntityImpl) predicate).isProcessInstanceType()) {
                            return false;
                        } else {
                            if (((ExecutionEntityImpl) predicate).isScope()) {
                                return false;
                            } else if (((ExecutionEntityImpl) predicate).isMultiInstanceRoot()) {
                                return false;
                            } else {
                                if (((ExecutionEntityImpl) predicate).isActive()) {
                                    return true;
                                } else {
                                    return false;
                                }
                            }
                        }
                    }
                    return false;
                }).collect(Collectors.toList());
                //根据时间进行排序
                hisTasks.sort(Comparator.comparing(HistoricActivityInstance::getEndTime));
                log.info("executions={}", executions);
                List<FlowTaskHistoryDTO> orderApprovalDTOS = new ArrayList<>();
                if (hisTasks.stream().map(HistoricActivityInstance::getActivityId).collect(Collectors.toList()).contains(executions.get(0).getActivityId())) {
                    int j = 0;
                    for (int i = 0; i < hisTasks.size(); ++i) {
                        if (hisTasks.get(i).getActivityId().equals(executions.get(0).getActivityId())) {
                            j = i;
                            break;
                        }
                    }
                    for (int i = 0; i < j; i++) {
                        HistoricActivityInstance historicActivityInstance = hisTasks.get(i);
                        FlowTaskHistoryDTO flowTaskHistoryDTO = new FlowTaskHistoryDTO();
                        flowTaskHistoryDTO.setTargetActivityId(historicActivityInstance.getActivityId());
                        flowTaskHistoryDTO.setTaskName(historicActivityInstance.getActivityName());
                        orderApprovalDTOS.add(flowTaskHistoryDTO);
                    }
                } else {
                    for (HistoricActivityInstance hisTask : hisTasks) {
                        FlowTaskHistoryDTO flowTaskHistoryDTO = new FlowTaskHistoryDTO();
                        flowTaskHistoryDTO.setTargetActivityId(hisTask.getActivityId());
                        flowTaskHistoryDTO.setTaskName(hisTask.getActivityName());
                        orderApprovalDTOS.add(flowTaskHistoryDTO);
                    }
                }

                return orderApprovalDTOS;
            } else {
                throw new APIException(APICode.DATA_ERROR, "驳回失败，找不到正在执行的任务！" + executions);
            }
        } else {
            throw new APIException(APICode.DATA_ERROR, "当前节点是第一节点,没有可以驳回的节点！" + procInstanceId);
        }

    }

    @Override
    public PageInfo<WfOrderResultDTO> myApplicationToDoOrder(WfOrderQueryDTO wfOrderQueryDTO) {
        Map<String, Object> params = buildQueryParams(wfOrderQueryDTO);
        params.put("createUserNo", wfOrderQueryDTO.getUserNo());
        return PageMethod.startPage(
                wfOrderQueryDTO.getPageNum(), wfOrderQueryDTO.getPageSize()).doSelectPageInfo(() -> wfOrderMapper.myApplicationToDoOrder(params));
    }

    @Override
    public PageInfo<WfOrderResultDTO> myApplicationRejectOrder(WfOrderQueryDTO wfOrderQueryDTO) {
        Map<String, Object> params = buildQueryParams(wfOrderQueryDTO);
        params.put("createUserNo", wfOrderQueryDTO.getUserNo());
        return PageMethod.startPage(
                wfOrderQueryDTO.getPageNum(), wfOrderQueryDTO.getPageSize()).doSelectPageInfo(() -> wfOrderMapper.myApplicationRejectOrder(params));
    }

    @Override
    public PageInfo<WfOrderResultDTO> myApplicationDoneOrder(WfOrderQueryDTO wfOrderQueryDTO) {
        Map<String, Object> params = buildQueryParams(wfOrderQueryDTO);
        params.put("createUserNo", wfOrderQueryDTO.getUserNo());
        return PageMethod.startPage(
                wfOrderQueryDTO.getPageNum(), wfOrderQueryDTO.getPageSize()).doSelectPageInfo(() -> wfOrderMapper.myApplicationDoneOrder(params));
    }

    @Override
    public PageInfo<WfOrderResultDTO> simulationOrderToDoTasks(WfOrderQueryDTO wfOrderQueryDTO) {
        Map<String, Object> params = buildQueryParams(wfOrderQueryDTO);
        params.putIfAbsent("appId", FlowConstant.SIMULATION_ORDER_APPID);
        return PageMethod.startPage(
                wfOrderQueryDTO.getPageNum(), wfOrderQueryDTO.getPageSize()).doSelectPageInfo(() -> wfOrderMapper.queryToDoTasksOrder(params));
    }

    @Override
    public PageInfo<WfOrderResultDTO> simulationOrderDoneTasks(WfOrderQueryDTO wfOrderQueryDTO) {
        Map<String, Object> params = buildQueryParams(wfOrderQueryDTO);
        params.putIfAbsent("appId", FlowConstant.SIMULATION_ORDER_APPID);
        return PageMethod.startPage(
                wfOrderQueryDTO.getPageNum(), wfOrderQueryDTO.getPageSize()).doSelectPageInfo(() -> wfOrderMapper.queryDoneTasksOrder(params));
    }

    @Override
    public List<WfTaskAssignNode> queryRejectTask(String taskId) {
        log.info("查询除当前节点外的其他用户节点");
        Task task = taskService.createTaskQuery().taskId(taskId).singleResult();
        if (task != null) {
            String processDefinitionId = task.getProcessDefinitionId();
            Example example = new Example(WfTaskAssign.class);
            example.createCriteria()
                    .andEqualTo("taskDefId", task.getTaskDefinitionKey())
                    .andEqualTo("procDefId", processDefinitionId);
            WfTaskAssign wfTaskAssign = wfTaskAssignMapper.selectOneByExample(example);
            if (wfTaskAssign != null) {
                Long id = wfTaskAssign.getId();
                Example example1 = new Example(WfTaskAssignNode.class);
                example1.createCriteria().andEqualTo("mainId", id);
                List<WfTaskAssignNode> wfTaskAssignNodes = wfTaskAssignNodeMapper.selectByExample(example1);
                if (CollectionUtils.isNotEmpty(wfTaskAssignNodes)) {
                    return wfTaskAssignNodes;
                }
            } else {
                throw new APIException(APICode.DATA_ERROR, "未找到此节点的相关配置！" + processDefinitionId);
            }
        }
        return null;
    }

    @Override
    public PageInfo<WfOrderResultDTO> toDoTasks(WfOrderQueryDTO wfOrderQueryDTO) {
        if (wfOrderQueryDTO.getAppId() != null) {
            /*
             * 根据平台appId得到调用类型
             */
            Map<String, Object> params = buildQueryParams(wfOrderQueryDTO);
            Example example = new Example(WfPlatformDef.class);
            example.createCriteria()
                    .andEqualTo("platformId", wfOrderQueryDTO.getAppId());
            WfPlatformDef wfPlatformDef = wfPlatformDefMapper.selectOneByExample(example);

            PageInfo<WfOrderResultDTO> result = PageMethod.startPage(
                    wfOrderQueryDTO.getPageNum(), wfOrderQueryDTO.getPageSize()).doSelectPageInfo(() -> wfOrderMapper.queryToDoTasks(params));
            result.getList().forEach(wfOrderResultDTO -> getDynamicForm(wfPlatformDef, wfOrderResultDTO));
            return result;

        } else {
            Map<String, Object> params = buildQueryParams(wfOrderQueryDTO);
            return PageMethod.startPage(
                    wfOrderQueryDTO.getPageNum(), wfOrderQueryDTO.getPageSize()).doSelectPageInfo(() -> wfOrderMapper.queryToDoTasks(params));
        }
    }

    @Override
    public PageInfo<WfOrderResultDTO> myAllTask(WfOrderQueryDTO wfOrderQueryDTO) {
        Map<String, Object> params = buildQueryParams(wfOrderQueryDTO);
        return PageMethod.startPage(
                wfOrderQueryDTO.getPageNum(), wfOrderQueryDTO.getPageSize()).doSelectPageInfo(() -> wfOrderMapper.myAllTask(params));

    }

    @Override
    public PageInfo<WfOrderResultDTO> myApplicationAllTask(WfOrderQueryDTO wfOrderQueryDTO) {
        Map<String, Object> params = buildQueryParams(wfOrderQueryDTO);
        params.put("createUserNo", wfOrderQueryDTO.getUserNo());
        return PageMethod.startPage(
                wfOrderQueryDTO.getPageNum(), wfOrderQueryDTO.getPageSize()).doSelectPageInfo(() -> wfOrderMapper.myApplicationAllTask(params));

    }

    @Override
    public PageInfo<WfOrderResultDTO> queryAllOrder(WfOrderQueryDTO wfOrderQueryDTO) {
        Map<String, Object> params = buildQueryParams(wfOrderQueryDTO);
        return PageMethod.startPage(
                wfOrderQueryDTO.getPageNum(), wfOrderQueryDTO.getPageSize()).doSelectPageInfo(() -> wfOrderMapper.queryAllOrder(params));
    }

    @Override
    public PageInfo<WfOrderResultDTO> queryAllRejectTasks(WfOrderQueryDTO wfOrderQueryDTO) {
        Map<String, Object> params = buildQueryParams(wfOrderQueryDTO);
        return PageMethod.startPage(
                wfOrderQueryDTO.getPageNum(), wfOrderQueryDTO.getPageSize()).doSelectPageInfo(() -> wfOrderMapper.queryAllRejectTasks(params));
    }

    @Override
    public PageInfo<WfOrderResultDTO> queryAllToDoTasks(WfOrderQueryDTO wfOrderQueryDTO) {
        Map<String, Object> params = buildQueryParams(wfOrderQueryDTO);
        return PageMethod.startPage(
                wfOrderQueryDTO.getPageNum(), wfOrderQueryDTO.getPageSize()).doSelectPageInfo(() -> wfOrderMapper.queryAllToDoTasks(params));
    }

    @Override
    public PageInfo<WfOrderResultDTO> queryAllDoneTasks(WfOrderQueryDTO wfOrderQueryDTO) {
        Map<String, Object> params = buildQueryParams(wfOrderQueryDTO);
        return PageMethod.startPage(
                wfOrderQueryDTO.getPageNum(), wfOrderQueryDTO.getPageSize()).doSelectPageInfo(() -> wfOrderMapper.queryAllDoneTasks(params));
    }


    @Override
    public WfOrderResponse queryOrderDetailBySa(WfOrderDetailQueryBySaDTO dto) {
        if (StringUtils.isBlank(dto.getProcessId())) {
            throw new APIException(APICode.INVALID_PARAMETER, "流程ID不能都为空！");
        }

        WfOrderResponse wfOrderResponse = new WfOrderResponse();
        //获得工单详情数据
        WfOrder order = new WfOrder();
        /*
         * 根据processId获取taskId，（多实例会签情况下，只取第一个任务），
         */
        order.setProcessId(dto.getProcessId());
        order = wfOrderMapper.selectOne(order);
        BeanUtils.copyProperties(order, wfOrderResponse);
        if (null == order) {
            log.warn("工单不存在！工单系统流程实例ID(processId)：{}", dto.getProcessId());
            throw new APIException(APICode.NOT_FOUND, "工单不存在！");
        }
        Task task = null;
        List<Task> list = taskService.createTaskQuery().active().processInstanceId(dto.getProcessId()).list();
        if (CollectionUtils.isNotEmpty(list)) {
            task = list.get(0);
            wfOrderResponse.setTaskId(task.getId());
            log.info("根据processId得到任务后，获取执行中任务的处理人");
            List<String> candidate = flowTaskServiceImpl.getCandidate(task);
            String substring = candidate.toString().substring(1, candidate.toString().length() - 1);
            wfOrderResponse.setProcessor(substring);
            wfOrderResponse.setCurrentNode(task.getName());
        } else {
            Execution exec = runtimeService.createExecutionQuery().processInstanceId(dto.getProcessId()).messageEventSubscriptionName(FLMsgEventEnum.DEFAULT.getEvent()).singleResult();
            if (exec != null) {
                List<ActivityInstance> aicts = runtimeService.createActivityInstanceQuery().activityId(exec.getActivityId()).unfinished().orderByActivityInstanceStartTime().desc().list();
                if (CollectionUtils.isNotEmpty(aicts)) {
                    wfOrderResponse.setCurrentNode(aicts.get(0).getActivityName());
                }
            }
        }

        WfPlatformDef wfPlatformDef = new WfPlatformDef();
        wfPlatformDef.setPlatformId(order.getAppId());
        wfPlatformDef = wfPlatformDefMapper.selectOne(wfPlatformDef);
        wfOrderResponse.setPlatformame(wfPlatformDef.getPlatformName());
        if (OrderStatus.PROCESSING.getCode().equals(order.getOrderStatus()) ||
                OrderStatus.REJECT.getCode().equals(order.getOrderStatus())) {
            wfOrderResponse.setTotalTime(DateUtil.getDistanceTime(DateUtils.getCurrent().getTime() - order.getCreateTime().getTime()));
        }
        log.info("获取流转历史列表");
        List<FlowTaskHistoryDTO> flowTaskHistoryDtoList = new ArrayList<>();
        if (StringUtils.isBlank(dto.getShowLevel())
                || "A".equals(dto.getShowLevel())) {
            flowTaskHistoryDtoList = flowTaskServiceImpl.queryTaskHistories(order.getProcessId());
        } else {
            flowTaskHistoryDtoList = flowTaskServiceImpl.queryHistoriesOfLevel(order.getProcessId(), dto.getShowLevel());
        }
        wfOrderResponse.setCommentList(flowTaskHistoryDtoList);

        log.info("处理消耗时间开始");
        for (FlowTaskHistoryDTO flowTaskHistoryDTO : flowTaskHistoryDtoList) {
            if (StringUtils.isNoneBlank(flowTaskHistoryDTO.getTimeConsuming())) {
                flowTaskHistoryDTO.setTimeConsuming(DateUtil.getDistanceTime(Long.parseLong(flowTaskHistoryDTO.getTimeConsuming()) / 1000 * 1000));
            }
        }

        log.info("获取所有流转节点");
        List<UserTaskDto> flowtaskList = flowTaskServiceImpl.queryProcessUserTasks(order.getProcessId());
        wfOrderResponse.setUserTaskList(flowtaskList);

        WfFormExample formExample = wfFormService.queryHistoryFormExample(order.getProcessId());

        if (formExample != null) {
            wfOrderResponse.setFormContent(formExample.getFormContent());
            wfOrderResponse.setFormData(formExample.getProcessData());
            wfOrderResponse.setFormName(formExample.getFormName());
        }
        return wfOrderResponse;
    }


}
